package io.gitee.chearnee.fw.openapi.advice;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.gitee.chearnee.fw.openapi.result.OpenApiResult;
import lombok.AllArgsConstructor;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.ParameterizedType;

/**
 * @author cn
 * @version 1.0
 * @date 2021/5/24 18:44
 */
@ControllerAdvice
@AllArgsConstructor
public class OpenApiResponseBodyAdvice implements ResponseBodyAdvice<Object> {

  private final ObjectMapper objectMapper;

  @Override
  public boolean supports(MethodParameter methodParameter,
      Class<? extends HttpMessageConverter<?>> converterType) {
      if (methodParameter.getGenericParameterType().equals(OpenApiResult.class)) {
          return false;
      }
      if (methodParameter.getGenericParameterType() instanceof ParameterizedType parameterizedType
              && parameterizedType.getRawType()
              .equals(OpenApiResult.class)) {
          return false;
      }
      EnableOpenApiResponseAdvice enableResponseAdvice = methodParameter.getDeclaringClass()
              .getAnnotation(
                      EnableOpenApiResponseAdvice.class);
      if (enableResponseAdvice == null) {
          enableResponseAdvice = methodParameter.getMethodAnnotation(EnableOpenApiResponseAdvice.class);
      }
      return enableResponseAdvice != null && enableResponseAdvice.enable();
  }

  @Override
  public Object beforeBodyWrite(Object body, MethodParameter methodParameter,
      MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
      ServerHttpRequest request, ServerHttpResponse response) {
    if (methodParameter.getGenericParameterType().equals(String.class)) {
      String s = null;
      try {
        s = objectMapper.writeValueAsString(OpenApiResult.success(body));
      } catch (JsonProcessingException e) {
        return OpenApiResult.fail("转换失败");
      }
      response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
      return s;
    }
//    //去掉分页处理
//    if (body instanceof IPage) {
//      return OpenApiResult.success(ResultPage.restPage((Page) body));
//    }
    return OpenApiResult.success(body);
  }
}
